if not _G.ElvUI or _G.ElvuiInfoLeft then
    return
end

local E, L, P, G = unpack(_G.ElvUI)
local DT = E:GetModule('DataTexts')

----------------------------------------
-- Local refs for speedup and lint's happiness
----------------------------------------
local _G = _G
local GameTooltip = _G.GameTooltip
local format = _G.format
local tinsert = _G.tinsert
local tsort = table.sort
local abs = _G.abs
local mod = _G.mod
local floor = _G.floor
local UIParent = _G.UIParent
local InCombatLockdown = _G.InCombatLockdown
local GetInventorySlotInfo = _G.GetInventorySlotInfo
local GetInventoryItemDurability = _G.GetInventoryItemDurability
local GetContainerNumFreeSlots = _G.GetContainerNumFreeSlots
local GetContainerNumSlots = _G.GetContainerNumSlots
local GetBackpackCurrencyInfo = _G.GetBackpackCurrencyInfo
local GetPrimaryTalentTree = _G.GetPrimaryTalentTree
local DURABILITY = _G.DURABILITY

----------------------------------------
-- bottom panel
----------------------------------------
local bpn = _G.CreateFrame("Frame", "ElvBottomFillerFrame", UIParent)
bpn:SetScript('OnEvent',
    function()
        local leftChatDataPanel = _G.LeftChatDataPanel

        bpn:SetFrameLevel(1)
        bpn:SetFrameStrata("BACKGROUND")
        bpn:SetTemplate("Default", true)
        bpn:ClearAllPoints()
        bpn:SetWidth(UIParent:GetWidth() - leftChatDataPanel:GetWidth()*2 - 41)
        bpn:SetHeight(leftChatDataPanel:GetHeight())
        bpn:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, leftChatDataPanel:GetBottom())
        bpn:SetScript('OnEvent', nil)
    end)
bpn:RegisterEvent('PLAYER_ENTERING_WORLD')

--------------------------------------------------------------------
-- recount datatext
--------------------------------------------------------------------
local healSpec = 0
local healSpec2 = 0
if E.myclass == "PALADIN" then
    healSpec = 1
elseif E.myclass == "SHAMAN" then
    healSpec = 3
elseif E.myclass == "DRUID" then
    healSpec = 3
elseif E.myclass == "PRIEST" then
    healSpec = 1
    healSpec2 = 2
end

local function isHealer()
    local spec = GetPrimaryTalentTree()
    return (spec == healSpec) or (spec == healSpec2)
end

local Recount = _G.Recount

local function FormatNum(value)
    if value < 10000 then
        return format("%.1f", value)
    elseif value < 100000 then
        return format("%d", floor(value))
    elseif value < 1000000 then
        return format("%.2fk", value / 1000)
    else
        return format("%.2fm", value / 1000000)
    end
end

local reportMode = "Current"      -- default report its current
---local reportMode = "Overall"     -- default report its overall

--local DataTextFormat = "raid"     -- Show raid dps/healing
local DataTextFormat = "personal"   -- Show my personal dps/healing

local function matchUnitGUID(unitname, guid)
    for _, data in pairs(Recount.db2.combatants) do
        if data.GuardianReverseGUIDs and data.GuardianReverseGUIDs[unitname] and data.GuardianReverseGUIDs[unitname].GUIDs then
            for _, v in pairs(data.GuardianReverseGUIDs[unitname].GUIDs) do
                if v == guid then
                    return true
                end
            end
        end
    end
    return false
end

local function getRaidValuePerSecond(tablename, mode)
    local mydps, dps, curdps = 0, 0, 0
    local sum, mysum = 0, 0
    local n = 0

    local sumTable = {}
    for _, data in pairs(Recount.db2.combatants) do
        if data.Fights and data.Fights[tablename] and (data.type == "Self" or data.type == "Grouped" or data.type == "Pet" or data.type == "Ungrouped") then
            if mode == "DPS" then
                sum, curdps = Recount:MergedPetDamageDPS(data, tablename)
            elseif mode == "Heal" then
                sum, curdps = Recount:MergedPetHealingDPS(data, tablename)
            end
            if (data.type ~= "Pet")
                or (not Recount.db.profile.MergePets
                    and data.Owner
                    and (Recount.db2.combatants[data.Owner].type == "Self"
                        or Recount.db2.combatants[data.Owner].type == "Grouped"
                        or Recount.db2.combatants[data.Owner].type == "Ungrouped"))
                or (not Recount.db.profile.MergePets
                    and data.Name
                    and data.GUID
                    and matchUnitGUID(data.Name, data.GUID))
            then
                dps = dps + curdps * 10
                if (data.type == "Self") then
                    mydps = curdps * 10
                    mysum = sum
                else
                    n = n + 1
                    sumTable[n] = sum
                end
            end
        end
    end

    local pos = 1
    for i = 1, n do
        if mysum < sumTable[i] then
            pos = pos + 1
        end
    end

    return math.floor(dps + 0.5) / 10, math.floor(mydps + 0.5) / 10, pos
end

local rdt_update_cooldown = 1
local function rdtUpdate(self, t)
    rdt_update_cooldown = rdt_update_cooldown - t
    if rdt_update_cooldown < 0 then
        local dataMode

        if isHealer() then
            dataMode = "Heal"
        else
            dataMode = "DPS"
        end

        local tableName
        if reportMode == "Overall" then
            tableName = "OverallData"
        elseif InCombatLockdown() then
            tableName = "CurrentFightData"
        else
            tableName = "LastFightData"
        end

        local rps, mydps, pos = getRaidValuePerSecond(tableName, dataMode)

        local txt
        if DataTextFormat == "personal" then
            txt = pos..":  "..E.media.hexvaluecolor..FormatNum(mydps)
        else
            txt = "R: "..E.media.hexvaluecolor..FormatNum(rps)
        end

        self.text:SetText(txt)
        rdt_update_cooldown = 1
    end
end

local function rdtForceUpdate(self)
    rdtUpdate(self, 1000)
end

local ConvertDataSet = {
    ["OverallData"] = "Overall Data",
    ["CurrentFightData"] = "Current Fight",
    ["LastFightData"] = "Last Fight"
}

local tthead = {r = 0.4, g = 0.78, b = 1}
local theal = {r = 0, g = 1, b = 0}
local tdamage = {r = 1, g = 0, b = 0}
local notgroup = {r = 0.35686274509804, g = 0.56470588235294, b = 0.031372549019608}
local colortable = {}
for class, color in pairs(_G.RAID_CLASS_COLORS) do
    colortable[class] = { r = color.r, g = color.g, b = color.b }
end
colortable["PET"] = {r = 0.09, g = 0.61, b = 0.55}
colortable["UNKNOWN"] = {r = 0.49803921568627, g = 0.49803921568627, b = 0.49803921568627}
colortable["MOB"] = {r = 0.58, g = 0.24, b = 0.63}
colortable["UNGROUPED"] = {r = 0.63, g = 0.58, b = 0.24}
colortable["HOSTILE"] = {r = 0.7, g = 0.1, b = 0.1}

local function getSumTable(tablename, mode)
    local data, fullname, totalsum, totalpersec, cursum, curpersec = nil, "", 0, 0, 0, 0

    local temptable = {}
    local sumtable = {}
    for _, data in pairs(Recount.db2.combatants) do
        if data.Fights and data.Fights[tablename] and (data.type == "Self" or data.type == "Grouped" or data.type == "Pet" or data.type == "Ungrouped") then
            if mode == "DPS" then
                cursum, curpersec = Recount:MergedPetDamageDPS(data, tablename)
            elseif mode == "Heal" then
                cursum, curpersec = Recount:MergedPetHealingDPS(data, tablename)
            end
            if data.type ~= "Pet" or (not Recount.db.profile.MergePets and data.Owner and (Recount.db2.combatants[data.Owner].type == "Self" or Recount.db2.combatants[data.Owner].type=="Grouped" or Recount.db2.combatants[data.Owner].type == "Ungrouped")) or (not Recount.db.profile.MergePets and data.Name and data.GUID and matchUnitGUID(data.Name, data.GUID)) then
                if cursum > 0 then
                    totalsum = totalsum + cursum
                    --curpersec = math.floor(curpersec + 0.5)
                    totalpersec = totalpersec + curpersec
                    fullname = data.Name or _G["UNKNOWN"]
                    if data.type == "Pet" then
                        fullname = data.Name.." <"..data.Owner..">"
                    end
                    if mode == "DPS" then
                        temptable = {name = fullname, damage = cursum, dps = curpersec, enclass = data.enClass}
                    elseif mode == "Heal" then
                        temptable = {name = fullname, healing = cursum, hps = curpersec, enclass = data.enClass}
                    end
                    tinsert(sumtable, temptable)
                end
            end
        end
    end
    if mode == "DPS" then
        tsort(sumtable, function(a, b) return a.damage > b.damage end)
    elseif mode == "Heal" then
        tsort(sumtable, function(a, b) return a.healing > b.healing end)
    end

    return sumtable, totalsum, totalpersec
end

local function DisplayTable(mode, repotType, amount)
    local statsTable, totalsum, totalpersec = getSumTable(mode, repotType)

    if repotType == "DPS" then
        GameTooltip:AddDoubleLine("Damage Done", ConvertDataSet[mode], tdamage.r, tdamage.g, tdamage.b, tthead.r, tthead.g, tthead.b)
    elseif repotType == "Heal" then
        GameTooltip:AddDoubleLine("Healing Done", ConvertDataSet[mode],theal.r, theal.g, theal.b, tthead.r, tthead.g, tthead.b)
    end

    local numofcombatants = #statsTable

    if numofcombatants == 0 then
        GameTooltip:AddLine("No data to display")
    else
        if numofcombatants > amount then
            numofcombatants = amount
        end
        GameTooltip:AddDoubleLine("Total", format("%s (%s) 100.0%%", FormatNum(totalsum), FormatNum(totalpersec)))
        for i = 1, numofcombatants do
            local classc

            if statsTable[i].enclass then
                classc = colortable[statsTable[i].enclass]
            else
                classc = notgroup
            end
            local persec, sum
            if repotType == "DPS" then
                persec = statsTable[i].dps
                sum = statsTable[i].damage
            else
                persec = statsTable[i].hps
                sum = statsTable[i].healing
            end
            GameTooltip:AddDoubleLine(format("%d. %s", i, statsTable[i].name), format("%s (%s) %.1f%%", FormatNum(sum), FormatNum(persec), 100*sum/totalsum), classc.r, classc.g, classc.b, classc.r, classc.g, classc.b)
        end
    end
end

local function CreateTooltipData(amount)
    if reportMode == "Overall" then
        DisplayTable("OverallData", "DPS", amount)

        GameTooltip:AddLine(" ")

        DisplayTable("OverallData", "Heal", amount)
    else
        if Recount.InCombat then
            DisplayTable("CurrentFightData", "DPS", amount)
        else
            DisplayTable("LastFightData", "DPS", amount)
        end

        GameTooltip:AddLine(" ")

        if Recount.InCombat then
            DisplayTable("CurrentFightData", "Heal", amount)
        else
            DisplayTable("LastFightData", "Heal", amount)
        end
    end
end

local function rdtOnEnter(self)
	DT:SetupTooltip(self)
    CreateTooltipData(10)
	GameTooltip:Show()
end

local function rdtClick(self, btn)
    if btn == "LeftButton" then
        GameTooltip:Hide()
        if Recount.MainWindow:IsShown() then
            Recount.MainWindow:Hide()
        else
            Recount.MainWindow:Show()
            Recount:RefreshMainWindow()
        end
    elseif btn == "MiddleButton" then
        GameTooltip:Hide()
        if DataTextFormat == "raid" then
            DataTextFormat = "personal"
        else
            DataTextFormat = "raid"
        end
        rdtForceUpdate(self)
    elseif btn == "RightButton" then
        if reportMode == "Current" then
            reportMode = "Overall"
        else
            reportMode = "Current"
        end
        rdtOnEnter(self)
    end
end

if _G.IsAddOnLoaded("Recount") then
    DT:RegisterDatatext('Recount', nil, nil, rdtUpdate, rdtClick, rdtOnEnter)
end

--------------------------------------------------------------------
-- COLORED DURABILITY (derived from elv's durability datatext)
--------------------------------------------------------------------
local function DurabilityColor(perc)
    if not perc or perc < 0 then return "|cFF555555" end
    if perc == 100 then
        return "|cFF005500" -- Dark green
    elseif perc >= 90 then
        return "|cFF00AA00" -- Green
    elseif perc > 50 then
        return "|cFFFFFF00" -- Yellow
    elseif perc > 20 then
        return "|cFFFF9900" -- Orange
    else
        return "|cFFFF0000" -- Red
    end
end

local slots = {
	["RangedSlot"] = L['Ranged'],
	["SecondaryHandSlot"] = L['Offhand'],
	["MainHandSlot"] = L['Main Hand'],
	["FeetSlot"] = L['Feet'],
	["LegsSlot"] = L['Legs'],
	["HandsSlot"] = L['Hands'],
	["WristSlot"] = L['Wrist'],
	["WaistSlot"] = L['Waist'],
	["ChestSlot"] = L['Chest'],
	["ShoulderSlot"] = L['Shoulder'],
	["HeadSlot"] = L['Head'],
}

local invDurability = {}

local function cddtOnEvent(self)
    local current, max
	local total = 0
	local totalDurability = 0
	local totalPerc = 0

	for index, value in pairs(slots) do
		local slot = GetInventorySlotInfo(index)
		current, max = GetInventoryItemDurability(slot)

		if current then
			totalDurability = totalDurability + current
			invDurability[value] = (current/max)*100
			totalPerc = totalPerc + (current/max)*100
			total = total + 1
		end
	end

    if total > 0 then
        self.text:SetText(DURABILITY..": "..DurabilityColor(totalPerc/total)..floor(totalPerc/total).."%")
    else
        self.text:SetText(DURABILITY..": "..E.media.hexvaluecolor.."100%")
    end
end

local function cddtOnEnter(self)
    DT:SetupTooltip(self)
    for slot, durability in pairs(invDurability) do
        GameTooltip:AddDoubleLine(slot, format('%d%%', durability), 1, 1, 1, E:ColorGradient(durability * 0.01, 1, 0, 0, 1, 1, 0, 0, 1, 0))
    end
    GameTooltip:Show()
end

local function cddtOnClick()
    _G.ToggleCharacter("PaperDollFrame")
end

DT:RegisterDatatext('CDurability', {'UPDATE_INVENTORY_DURABILITY', 'MERCHANT_SHOW', 'PLAYER_ENTERING_WORLD'}, cddtOnEvent, nil, cddtOnClick, cddtOnEnter)

--------------------------------------------------------------------
 -- COLORED BAGS
--------------------------------------------------------------------
local function cbdtOnEvent(self)
    local free, total, used = 0, 0, 0
    local color

    for i = 0, _G['NUM_BAG_SLOTS'] do
        free, total = free + GetContainerNumFreeSlots(i), total + GetContainerNumSlots(i)
    end
    if free > (total / 2) then
      color = E.media.hexvaluecolor
    elseif free < (total / 3) then
      color = "|cffff0000"
    else
      color = "|cfffed100"
    end
    self.text:SetText('Bags: '..color..free.."/"..total)
end

local function cbdtOnClick()
    _G.ToggleAllBags()
end

local function FormatTooltipMoney(money)
	if not money then return end
	local gold, silver, copper = abs(money / 10000), abs(mod(money / 100, 100)), abs(mod(money, 100))
	local cash = ""
	cash = format("%d"..L.goldabbrev.." %d"..L.silverabbrev.." %d"..L.copperabbrev, gold, silver, copper)
	return cash
end

local function cbdtOnEnter(self)
    DT:SetupTooltip(self)

	GameTooltip:AddDoubleLine('Gold', FormatTooltipMoney(_G.GetMoney()), 1, 1, 1, 1, 1, 1)

	for i = 1, _G.MAX_WATCHED_TOKENS do
		local name, count, extraCurrencyType, icon, itemID = GetBackpackCurrencyInfo(i)

		if name and i == 1 then
			GameTooltip:AddLine(" ")
			GameTooltip:AddLine(_G.CURRENCY)
		end
		if name and count then
            GameTooltip:AddDoubleLine(name, count, 1, 1, 1)
        end
	end

    GameTooltip:Show()
end

DT:RegisterDatatext('CBags', {'PLAYER_LOGIN', 'BAG_UPDATE'}, cbdtOnEvent, nil, cbdtOnClick, cbdtOnEnter)

----------------------------------------
-- Error filter
----------------------------------------
local error_filter = {
	[ERR_ATTACK_CHANNEL] = true,
	[ERR_ATTACK_CHARMED] = true,
	[ERR_ATTACK_CONFUSED] = true,
	[ERR_ATTACK_FLEEING] = true,
	[ERR_ATTACK_MOUNTED] = true,
	[ERR_ATTACK_PACIFIED] = true,
	[ERR_ATTACK_PREVENTED_BY_MECHANIC_S] = true,
	[ERR_ATTACK_STUNNED] = true,
	[ERR_AUTOFOLLOW_TOO_FAR] = true,
	[ERR_BADATTACKFACING] = true,
	[ERR_BADATTACKPOS] = true,
	[ERR_CANTATTACK_NOTSTANDING] = true,
	[ERR_GENERIC_NO_TARGET] = true,
	[ERR_GENERIC_STUNNED] = true,
	[ERR_INVALID_ATTACK_TARGET] = true,
	[ERR_ITEM_COOLDOWN] = true,
	[ERR_LOOT_BAD_FACING] = true,
	[ERR_LOOT_STUNNED] = true,
	[ERR_NOT_IN_COMBAT] = true,
	[ERR_NOT_WHILE_DISARMED] = true,
	[ERR_NOT_WHILE_FALLING] = true,
	[ERR_NOT_WHILE_FATIGUED] = true,
	[ERR_NOT_WHILE_MOUNTED] = true,
	[ERR_NO_ATTACK_TARGET] = true,
	[ERR_ABILITY_COOLDOWN] = true,
	[ERR_OUT_OF_ENERGY] = true,
	[ERR_OUT_OF_FOCUS] = true,
	[ERR_OUT_OF_HEALTH] = true,
	[ERR_OUT_OF_MANA] = true,
	[ERR_OUT_OF_POWER_DISPLAY] = true,
	[ERR_OUT_OF_RAGE] = true,
	[ERR_OUT_OF_RANGE] = true,
	[ERR_OUT_OF_RUNES] = true,
	[ERR_OUT_OF_HOLY_POWER] = true,
	[ERR_OUT_OF_SOUL_SHARDS] = true,
	[ERR_OUT_OF_RUNIC_POWER] = true,
	[ERR_PET_SPELL_AFFECTING_COMBAT] = true,
	[ERR_PET_SPELL_NOT_BEHIND] = true,
	[ERR_PET_SPELL_OUT_OF_RANGE] = true,
	[ERR_PET_SPELL_ROOTED] = true,
	[ERR_PET_SPELL_TARGETS_DEAD] = true,
	[ERR_PLAYER_WRONG_FACTION] = true,
	[ERR_SPELL_COOLDOWN] = true,
	[ERR_SPELL_FAILED_ALREADY_AT_FULL_HEALTH] = true,
	[ERR_SPELL_FAILED_ALREADY_AT_FULL_MANA] = true,
	[ERR_SPELL_FAILED_ALREADY_AT_FULL_POWER_S] = true,
	[ERR_SPELL_OUT_OF_RANGE] = true,
	[ERR_TARGET_STUNNED] = true,
	[ERR_TOO_FAR_TO_ATTACK] = true,
	[ERR_TOO_FAR_TO_INTERACT] = true,
	[ERR_USE_BAD_ANGLE] = true,
	[ERR_USE_CANT_IMMUNE] = true,
	[ERR_USE_PREVENTED_BY_MECHANIC_S] = true,
	[ERR_USE_TOO_FAR] = true,
	[ERR_SPELL_COOLDOWN] = true,
	[NOT_ENOUGH_MANA] = true,
	[OUT_OF_ENERGY] = true,
	[OUT_OF_FOCUS] = true,
	[OUT_OF_HEALTH] = true,
	[OUT_OF_MANA] = true,
	[OUT_OF_POWER_DISPLAY] = true,
	[OUT_OF_RAGE] = true,
	[PETTAME_DEAD] = true,
	[PET_SPELL_NOPATH] = true,

	[SPELL_FAILED_AFFECTING_COMBAT] = true,
	[SPELL_FAILED_AURA_BOUNCED] = true,
	[SPELL_FAILED_BAD_IMPLICIT_TARGETS] = true,
	[SPELL_FAILED_BAD_TARGETS] = true,
	[SPELL_FAILED_CANT_BE_CHARMED] = true,
	[SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW] = true,
	[SPELL_FAILED_CANT_STEALTH] = true,
	[SPELL_FAILED_CASTER_AURASTATE] = true,
	[SPELL_FAILED_CONFUSED] = true,
	[SPELL_FAILED_CUSTOM_ERROR_28] = true,
	[SPELL_FAILED_CUSTOM_ERROR_44] = true,
	[SPELL_FAILED_CUSTOM_ERROR_45] = true,
	[SPELL_FAILED_LINE_OF_SIGHT] = true,
	[SPELL_FAILED_FLEEING] = true,
	[SPELL_FAILED_CUSTOM_ERROR_54] = true,
	[SPELL_FAILED_CUSTOM_ERROR_56] = true,
	[SPELL_FAILED_CUSTOM_ERROR_57] = true,
	[SPELL_FAILED_CUSTOM_ERROR_64_NONE] = true,
	[SPELL_FAILED_CUSTOM_ERROR_76] = true,
	[SPELL_FAILED_DAMAGE_IMMUNE] = true,
	[SPELL_FAILED_INTERRUPTED] = true,
	[SPELL_FAILED_MOVING] = true,
	[SPELL_FAILED_NOPATH] = true,
	[SPELL_FAILED_NOTHING_TO_DISPEL] = true,
	[SPELL_FAILED_NOTHING_TO_STEAL] = true,

	[SPELL_FAILED_NOT_BEHIND] = true,
	[SPELL_FAILED_NOT_INFRONT] = true,
	[SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE] = true,
	[SPELL_FAILED_NOT_ON_STEALTHED] = true,
	[SPELL_FAILED_NOT_ON_SHAPESHIFT] = true,
	[SPELL_FAILED_NO_COMBO_POINTS] = true,
	[SPELL_FAILED_NO_EDIBLE_CORPSES] = true,
	[SPELL_FAILED_ONLY_STEALTHED] = true,
	[SPELL_FAILED_OUT_OF_RANGE] = true,
	[SPELL_FAILED_PACIFIED] = true,
	[SPELL_FAILED_POSSESSED] = true,
	[SPELL_FAILED_PREVENTED_BY_MECHANIC] = true,

	[SPELL_FAILED_ROOTED] = true,
	[SPELL_FAILED_SILENCED] = true,
	[SPELL_FAILED_SPELL_IN_PROGRESS] = true,
	[SPELL_FAILED_STUNNED] = true,
	[SPELL_FAILED_TARGETS_DEAD] = true,
	[SPELL_FAILED_TARGET_AFFECTING_COMBAT] = true,
	[SPELL_FAILED_TARGET_AURASTATE] = true,
	[SPELL_FAILED_TARGET_ENEMY] = true,
	[SPELL_FAILED_TARGET_FRIENDLY] = true,
	[SPELL_FAILED_TARGET_IN_COMBAT] = true,
	[SPELL_FAILED_TARGET_IS_PLAYER] = true,
	[SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED] = true,

	[SPELL_FAILED_TARGET_NOT_PLAYER] = true,
	[SPELL_FAILED_TOO_CLOSE] = true,
	[SPELL_FAILED_UNIT_NOT_BEHIND] = true,
	[SPELL_FAILED_UNIT_NOT_INFRONT] = true,
}

local error_filter_frame = CreateFrame("Frame")
error_filter_frame:SetScript("OnEvent",
    function(self, event, error)
        if (not error_filter[error]) and (not InCombatLockdown()) then
            UIErrorsFrame:AddMessage(error, 1, 0 ,0)
        end
end)
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE")
error_filter_frame:RegisterEvent("UI_ERROR_MESSAGE")

--------------------------------------------------------------------------
-- auto-greed green item at max level
--------------------------------------------------------------------------
local autogreed = CreateFrame("frame")
autogreed:RegisterEvent("START_LOOT_ROLL")
autogreed:SetScript("OnEvent", function(self, event, id)
    if E.level ~= MAX_PLAYER_LEVEL then return end
    if id and select(4, GetLootRollItemInfo(id)) == 2 and not (select(5, GetLootRollItemInfo(id))) then
        RollOnLoot(id, 2)
    end
end)

----------------------------------------
local tAutoAcceptInvite = CreateFrame("Frame")
tAutoAcceptInvite:RegisterEvent("PARTY_INVITE_REQUEST")
tAutoAcceptInvite:RegisterEvent("PARTY_MEMBERS_CHANGED")

local hidestatic -- used to hide static popup when auto-accepting

tAutoAcceptInvite:SetScript("OnEvent", function(self, event, ...)
    local arg1 = ...
    local leader = arg1
    local ingroup = false

    if event == "PARTY_INVITE_REQUEST" then
        if MiniMapLFGFrame:IsShown() then return end -- Prevent losing que inside LFD if someone invites you to group
        if GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 then return end
        hidestatic = true

        -- Update Guild and Friendlist
        if GetNumFriends() > 0 then ShowFriends() end
        if IsInGuild() then GuildRoster() end

        for friendIndex = 1, GetNumFriends() do
            local friendName = GetFriendInfo(friendIndex)
            if friendName == leader then
                AcceptGroup()
                ingroup = true
                break
            end
        end

        if not ingroup then
            for guildIndex = 1, GetNumGuildMembers(true) do
                local guildMemberName = GetGuildRosterInfo(guildIndex)
                if guildMemberName == leader then
                    AcceptGroup()
                    break
                end
            end
        end
    elseif event == "PARTY_MEMBERS_CHANGED" and hidestatic == true then
        StaticPopup_Hide("PARTY_INVITE")
        hidestatic = false
    end
end)

----------------------------------------
-- error frame toggle override
----------------------------------------
E.Misc.ErrorFrameToggle = function() end -- do nothing, handle errors by old way
